import { CLEAR_AUTH_DECORATOR_KEY } from '@libs/common';
import { CanActivate, ExecutionContext, Inject, Injectable, UnauthorizedException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { Reflector } from '@nestjs/core';
import { JwtService } from '@nestjs/jwt';
import { Observable } from 'rxjs';

@Injectable()
export class AuthGuard implements CanActivate {

  @Inject()
  private reflector: Reflector

  @Inject()
  private jwtService: JwtService

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest();
    const isClearAuth = this.reflector.get<boolean>(CLEAR_AUTH_DECORATOR_KEY, context.getClass()) || this.reflector.get<boolean>(CLEAR_AUTH_DECORATOR_KEY, context.getHandler());
    // 不需要token，直接放行
    if(isClearAuth) {
      return true
    }
    const token = this.extractTokenFromHeader(request);
    if (!token) {
      throw new UnauthorizedException();
    }
    try {
      const payload = await this.jwtService.verifyAsync(token);
      request['user'] = payload;
    } catch {
      throw new UnauthorizedException();
    }
    return true;
  }

  private extractTokenFromHeader(request: Request): string | undefined {
    // @ts-ignore
    const authorization = request.headers.authorization ?? ''
    const [type, token] = authorization?.split(' ') ?? [];
    return type === 'Bearer' ? token : undefined;
  }
}
